package MetroLab.Path;
import MetroLab.Utils.*;
import com.sun.j3d.utils.geometry.*;
import javax.media.j3d.*;
import javax.vecmath.*;
/**
 *
 * @author plus
 */
public class RailModelFactory {
    //private static Group Model10MLift=ObjectFactory.createObject("Model.Rail.10MLift",true);
    //private static Group Model10MGround=ObjectFactory.createObject("Model.Rail.10MGround",true);
    //private static Group Model10MLiftInner, Model10MLiftOutter;
    private static Group Model10MDualRail=ObjectFactory.createObject("Model.Rail.10MDual",true);
    private static Group Model50MDaozha=ObjectFactory.createObject("Rail.Bridage.50MDaozha",true);
    private static Group Model50MDaozhaStation=ObjectFactory.createObject("Rail.Bridage.50MDaozhaStation",true);
    private static Group Model50MLiftBridge=ObjectFactory.createObject("Rail.Bridage.50MLift",true);
    private static Rail MyRail;
    
    public RailModelFactory(Rail rail) {
        MyRail=rail;
        PosPoint pos= new PosPoint();
        pos.pos=new Point3d(0,0,0.8);
        //Model10MLiftInner=applyTransform(pos, Model10MLift);
        pos.pos=new Point3d(0,0,-0.8);
        //pos.AngV=Math.PI;
        //Model10MLiftOutter=applyTransform(pos, Model10MLift);
    }
  
    
    public Group MakeRail(double s, double t){
        Group res=new Group();
        PosPoint p=new PosPoint();
        double length=t-s;
        int segments=(int)length/50+1;
        //res.addChild(Model10MLift);
        for (int i=0; i<segments; i++){
            p.d=s+i*50;
            p=MyRail.makePath(p);
            res.addChild(applyTransform(s+i*50d,t,Model10MDualRail,true,5));
        }
        return res;
    }
    
    public Group MakeBase(double s, double t){
        Group res=new Group();
        PosPoint p=new PosPoint();
        double length=t-s;
        int segments=(int)length/50+1;
        for (int i=0; i<segments; i++){
            p.d=s+i*50d;
            p=MyRail.makePath(p);
            switch (p.PATH_TYPE){
                case PosPoint.PATH_SINGLE_LIFT:{
                    res.addChild(applyTransform(s+i*50d,t,Model50MLiftBridge,true));
                    //res.addChild(applyTransform(s+i*50d,t,Model50MDaozha,true));
                    break;
                }
                case PosPoint.PATH_STATION:{
                    res.addChild(applyTransform(s+i*50d,t,Model50MDaozhaStation,true));
                    //res.addChild(applyTransform(s+i*50d,t,Model50MDaozha,true));
                    break;
                }
                case PosPoint.PATH_GROUND:{
                    res.addChild(applyTransform(s+i*50d,t,Model50MDaozha,true));
                    //res.addChild(applyTransform(s+i*50d,t,Model50MDaozha,true));
                    break;
                }
            }
            
        }
        return res;
    }
    private Group applyTransform(double start,double end, Group g, boolean liftFix, double lengthIncrease){
        Group res;
        res=(Group)g.cloneTree();
        Transform3D transH=new Transform3D(),transV=new Transform3D(), transT=new Transform3D();
        PosPoint p=new PosPoint();
        for (int i=0; i<res.numChildren(); i++){
                Node n=res.getChild(i);
                if (n instanceof Shape3D){
                    Shape3D shape=(Shape3D)n;
                    for (int j=0; j<shape.numGeometries();j++ ){
                        Geometry geo=shape.getGeometry(j);
                        if (geo instanceof GeometryArray){
                            GeometryArray geoArray=(GeometryArray) geo;
                            Point3f [] tempCoord;//=new Point3f();
                            GeometryInfo geoInfo=new GeometryInfo(geoArray);

                            tempCoord = geoInfo.getCoordinates();
                            for(int v=0; v<tempCoord.length; v++){
                                if(start+tempCoord[v].x*lengthIncrease<=end){
                                    p.d=start+tempCoord[v].x*lengthIncrease;
                                }else{
                                    p.d=end;
                                    
                                }
                                p=MyRail.makePath(p);
                                if (!liftFix || tempCoord[v].y>-5)
                                    transH.rotX(p.AngH);
                                   
                                transV.rotY(p.AngV);
                                transT.set(new Vector3d(p.pos.x,p.pos.y,p.pos.z));
                                
                                transT.mul(transV);
                                transT.mul(transH);
                                tempCoord[v].x=0;
                                transT.transform(tempCoord[v]);
                            }
                            geoInfo.setCoordinates(tempCoord);
                            ((Shape3D)res.getChild(i)).setGeometry(geoInfo.getGeometryArray(true,false,true));
                        }
                    }
                }
            }
        return res;
        
    }
    private Group applyTransform(double start,double end, Group g, boolean liftFix){
        return applyTransform(start,end,g,liftFix,1d);
    }
    private Group applyTransform(double start,double end, Group g){
        return applyTransform(start,end,g,false,1d);
        
    }
    
     /*Group applyTransform(PosPoint p, Group g){
        Transform3D transH=new Transform3D();
        transH.rotX(p.AngH);
        Transform3D transV=new Transform3D();
        transV.rotY(p.AngV);
        Transform3D transT=new Transform3D();
        transT.set(new Vector3d(p.pos.x,p.pos.y,p.pos.z));
        
        transT.mul(transV);
        transT.mul(transH);
        
        Group res;
        res=(Group)g.cloneTree();
        for (int i=0; i<res.numChildren(); i++){
                Node n=res.getChild(i);
                if (n instanceof Shape3D){
                    Shape3D shape=(Shape3D)n;
                    for (int j=0; j<shape.numGeometries();j++ ){
                        Geometry geo=shape.getGeometry(j);
                        if (geo instanceof GeometryArray){
                            GeometryArray geoArray=(GeometryArray) geo;
                            Point3f [] tempCoord;//=new Point3f();
                            GeometryInfo geoInfo=new GeometryInfo(geoArray);
                            tempCoord = geoInfo.getCoordinates();
                            for(int v=0; v<tempCoord.length; v++){
                                transT.transform(tempCoord[v]);
                            }
                            geoInfo.setCoordinates(tempCoord);
                            ((Shape3D)res.getChild(i)).setGeometry(geoInfo.getGeometryArray(true,false,true));
                        }
                    }
                }
            }
        return res;
    }*/
}
